
const { app, BrowserWindow,Menu, ipcMain, dialog, nativeTheme } = require('electron')
const path = require('path')
const fs = require('fs')

/**
 * 创建主窗口
 * 
 * 该函数初始化并配置了应用程序的主窗口。它定义了窗口的大小、隐藏菜单栏、图标以及预加载脚本等设置。
 * 这些设置旨在提供一个适合应用程序运行的基本环境，并准备加载应用程序的主界面。
 */
const createWindow = () => {
    // 创建一个新的BrowserWindow实例，并配置其属性
    const mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        autoHideMenuBar: true,
        icon: path.join(__dirname,"favicon.ico"),
        webPreferences: {
            preload: path.join(__dirname, 'preload.js')
        }
    })
    const menu = Menu.buildFromTemplate([
        {
          label: app.name,
          submenu: [
            {
              click: () => mainWindow.webContents.send('update-counter', 1),
              label: 'Increment'
            },
            {
              click: () => mainWindow.webContents.send('update-counter', -1),
              label: 'Decrement'
            }
          ]
        }
      ])
      Menu.setApplicationMenu(menu)
    // 默认打开调试工具
    // mainWindow.webContents.openDevTools()

    // 加载应用程序的主界面
    mainWindow.loadFile('./src/index.html')
}
/**
 * 将数据写入指定文件。
 * 
 * 本函数用于将提供的数据写入到硬编码路径（D:/hello.txt）的文件中。
 * 它使用了Node.js的fs模块的writeFileSync方法，同步地写入数据到文件。
 * 这种同步操作在文件系统操作较多或对性能要求不高的场景下适用。
 * 
 * @param _ 该参数未使用，保留以符合函数式编程习惯。
 * @param data 要写入文件的内容。可以是字符串、对象等，根据实际需要进行转换。
 * 
 * 注意：由于函数使用了硬编码路径，这限制了函数的通用性和可迁移性。
 * 在实际应用中，建议使用动态路径或配置文件来指定文件路径，以提高灵活性。
 */
function writeFile(_,data) {
    fs.writeFileSync('D:/hello.txt', data)
}
/**
 * 读取并返回文件内容的函数
 * 
 * 该函数使用Node.js的fs模块同步地读取指定路径的文件。
 * 它不接受任何参数，直接返回读取到的文件内容的字符串形式。
 * 
 * @returns {string} 返回读取的文件内容，以字符串形式呈现
 */
function readFile() {
    return fs.readFileSync('D:/hello.txt').toString()
}

function handleSetTitle (event, title) {
    const webContents = event.sender
    const win = BrowserWindow.fromWebContents(webContents)
    win.setTitle(title)
}

async function handleFileOpen () {
    const { canceled, filePaths } = await dialog.showOpenDialog()
    if (!canceled) {
      return filePaths[0]
    }
  }

// 当应用程序准备就绪时，执行一系列初始化操作
app.whenReady().then(() => {
    /**
     * 设置IPC（Inter-Process Communication）处理程序，用于处理来自渲染进程的'ping'请求
     * 返回'pong'，实现简单的通信验证或同步请求响应机制。
     */
    // 双向 IPC 的一个常见应用是从渲染器进程代码调用主进程模块并等待结果。 
    // 这可以通过将 ipcRenderer.invoke 与 ipcMain.handle 搭配使用来完成。
    ipcMain.handle('ping', () => 'pong')

    /**
     * 注册一个IPC监听器，用于处理来自渲染进程的'saveFile'事件
     * 该事件通常由用户触发，例如保存文件的操作。
     * @param {Event} event IPC事件对象
     * @param {string} filePath 要保存的文件路径
     * @param {string} content 要保存的文件内容
     */
    // 要将单向 IPC 消息从渲染器进程发送到主进程，您
    // 可以使用 ipcRenderer.send API 发送消息，然后使用 ipcMain.on API 接收。
    ipcMain.on('saveFile', writeFile)

    /**
     * 设置IPC处理程序，用于处理来自渲染进程的'readFile'请求
     * 该请求可能是为了获取特定文件的内容。
     * @returns {Promise<FileContents>} 返回一个承诺，该承诺解析为文件内容。
     */
    ipcMain.handle('readFile', readFile)

    /**
     * 注册一个IPC监听器，用于处理来自渲染进程的'set-title'事件
     * 该事件用于设置应用程序窗口的标题。
     * @param {Event} event IPC事件对象
     * @param {string} title 新的窗口标题
     */
    ipcMain.on('set-title', handleSetTitle)

    ipcMain.handle('dialog:openFile', handleFileOpen)

    ipcMain.handle('dark-mode:toggle', () => {
        if (nativeTheme.shouldUseDarkColors) {
          nativeTheme.themeSource = 'light'
        } else {
          nativeTheme.themeSource = 'dark'
        }
        return nativeTheme.shouldUseDarkColors
      })
      
      ipcMain.handle('dark-mode:system', () => {
        nativeTheme.themeSource = 'system'
      })

    // 创建主应用程序窗口
    createWindow()

    // 当应用程序被激活（例如，从 dock 或任务栏点击）时，检查是否有窗口存在，
    // 如果没有，则创建新的窗口。
    app.on('activate', () => {
        if (BrowserWindow.getAllWindows().length === 0) {
            createWindow()
        }
    })
})

app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') {
        app.quit()
    }
})